/* ======================================================================================== *\

		FILE:				ForwardRenderer.h
		AUTHOR:				Jack Hoxley

		DESCRIPTION:		An implementation of traditional forward rendering.

		CHANGE:				14th July 2007
								Defined basic interface
							25th August 2007
								Replaced GetRotationMatrixForSegment() with GetRotationMatrixForVector()
							8th September 2007
								Added normal vector to 'SimpleVertex'

\* ======================================================================================== */

#ifndef INC_FORWARDRENDERER_H
#define INC_FORWARDRENDERER_H

// Include Standard Headers
// ------------------------
#include "DXUT.h"



// Include project headers
// -----------------------
#include "Utils.h"
#include "Profiling.h"
#include "PipeLayout.h"
#include "PipeRenderer.h"


namespace Renderer
{
	struct SimpleVertex
	{
		D3DXVECTOR3 p;
		D3DXVECTOR3 n;
		float w;
	};

	class ForwardRenderer : public PipeRenderer
	{
		public:
			
			// Constructors
			// ============
			ForwardRenderer( );
			~ForwardRenderer( );

			// Required operations
			// ===================
			HRESULT CreateResources( ID3D10Device* pDevice, const PipeSim::PipeLayout * const p );
			HRESULT UpdateResources( const PipeSim::PipeLayout * const p );
			HRESULT DestroyResources();

			HRESULT Render( ID3D10Device* pDevice, D3DXMATRIX& mViewProj );

			UINT32 VideoMemoryStorageInUse();
			void RendererName( wchar_t* wcDestination, const size_t& DestinationSize );

			// Additional operations
			// =====================

		private:
			// Following standard operations don't really have
			// a useful meaning in the context of this class
			ForwardRenderer( const ForwardRenderer& copy );
			bool operator == ( const ForwardRenderer& rhs );
			ForwardRenderer& operator = ( const ForwardRenderer& rhs );

			// D3D 10 resources
			ID3D10Effect* m_pEffect;

			struct PipeResources
			{
				ID3D10Buffer*  m_pVertexBuffer;
				ID3D10Buffer* m_pIndexBuffer;
				UINT32 m_LastUpdated;
				ID3D10EffectTechnique* m_pTechnique;
				ID3D10InputLayout** m_ppInputLayouts;
				UINT32 m_PipeLength;
				UINT32 m_VertexCount;
				UINT32 m_IndexCount;
			};

			UINT16 m_PipeCount;
			PipeResources** m_ppPipe;

			// General stats
			UINT32 m_VRAMBytes;

			HRESULT CreateIndividualPipe( PipeResources* p, const UINT16& MaximumPipeLength, ID3D10Device* pDevice );
			HRESULT UpdateIndividualPipe( PipeResources* p, const Utils::CoordinateList& coords, const UINT16& xSize, const UINT16& ySize, const UINT16& zSize, const UINT32& CurrLen );
			HRESULT DestroyIndividualPipe( PipeResources* p );
			void CreatePipeSegment( SimpleVertex* ppDestination, const D3DXVECTOR3& mid_point, const float& height, const float& width, const float& weight, const D3DXMATRIX& mCurr, const D3DXMATRIX& mNext );
			D3DXMATRIX GetRotationMatrixForVector( const Utils::IntegerVector& vec );
	};
};

#endif // INC_FORWARDRENDERER_H